package ini

import (
	"fmt"
	"github.com/danfwing/sd-project/pkg/config"
	"github.com/streadway/amqp"
)

var (
	GRabbitMQ        *amqp.Connection
	GRabbitMQChannel *amqp.Channel
)

// InitRabbitMQ 初始化RabbitMQ连接
func InitRabbitMQ(c *config.Config) error {
	cfg := c.RabbitMQ
	url := fmt.Sprintf("amqp://%s:%s@%s:%s/%s",
		cfg.Username,
		cfg.Password,
		cfg.Host,
		cfg.Port,
		cfg.VHost,
	)

	// 建立连接
	conn, err := amqp.Dial(url)
	if err != nil {
		return fmt.Errorf("rabbitmq connection error: %v", err)
	}
	GRabbitMQ = conn

	// 创建通道
	ch, err := conn.Channel()
	if err != nil {
		return fmt.Errorf("create channel error: %v", err)
	}
	GRabbitMQChannel = ch

	// 声明交换机
	if err := declareExchanges(ch, cfg); err != nil {
		return err
	}

	// 声明队列
	if err := declareQueues(ch, cfg); err != nil {
		return err
	}

	// 绑定队列
	if err := bindQueues(ch, cfg); err != nil {
		return err
	}

	return nil
}

// declareExchanges 声明交换机
func declareExchanges(ch *amqp.Channel, cfg config.RabbitMQConfig) error {
	// SMS交换机
	err := ch.ExchangeDeclare(
		cfg.Exchange.SMS, // name
		"direct",         // type
		true,             // durable
		false,            // auto-deleted
		false,            // internal
		false,            // no-wait
		nil,              // arguments
	)
	if err != nil {
		return fmt.Errorf("declare sms exchange error: %v", err)
	}

	// Email交换机
	err = ch.ExchangeDeclare(
		cfg.Exchange.Email, // name
		"direct",           // type
		true,               // durable
		false,              // auto-deleted
		false,              // internal
		false,              // no-wait
		nil,                // arguments
	)
	if err != nil {
		return fmt.Errorf("declare email exchange error: %v", err)
	}

	return nil
}

// declareQueues 声明队列
func declareQueues(ch *amqp.Channel, cfg config.RabbitMQConfig) error {
	// SMS队列
	_, err := ch.QueueDeclare(
		cfg.Queue.SMS, // name
		true,          // durable
		false,         // delete when unused
		false,         // exclusive
		false,         // no-wait
		nil,           // arguments
	)
	if err != nil {
		return fmt.Errorf("declare sms queue error: %v", err)
	}

	// Email队列
	_, err = ch.QueueDeclare(
		cfg.Queue.Email, // name
		true,            // durable
		false,           // delete when unused
		false,           // exclusive
		false,           // no-wait
		nil,             // arguments
	)
	if err != nil {
		return fmt.Errorf("declare email queue error: %v", err)
	}

	return nil
}

// bindQueues 绑定队列到交换机
func bindQueues(ch *amqp.Channel, cfg config.RabbitMQConfig) error {
	// 绑定SMS队列
	err := ch.QueueBind(
		cfg.Queue.SMS,      // queue name
		cfg.RoutingKey.SMS, // routing key
		cfg.Exchange.SMS,   // exchange
		false,
		nil,
	)
	if err != nil {
		return fmt.Errorf("bind sms queue error: %v", err)
	}

	// 绑定Email队列
	err = ch.QueueBind(
		cfg.Queue.Email,      // queue name
		cfg.RoutingKey.Email, // routing key
		cfg.Exchange.Email,   // exchange
		false,
		nil,
	)
	if err != nil {
		return fmt.Errorf("bind email queue error: %v", err)
	}

	return nil
}

// CloseRabbitMQ 关闭RabbitMQ连接
func CloseRabbitMQ() {
	if GRabbitMQChannel != nil {
		GRabbitMQChannel.Close()
	}
	if GRabbitMQ != nil {
		GRabbitMQ.Close()
	}
}
